#!/usr/bin/perl
# sipsak-notify.pl
# Copyright (C) 2006, 2007  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

# Assess the number of messages in <dir>/INBOX and <dir>/Old,
# then notify <context>/<extension> to turn MWI on or off accordingly.
# Note: this is an Unsollicted-NOTIFY type of MWI. Not all devices may support it.

use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use Sys::Syslog;

# Exit after 20 seconds (for example if sipsak doesn't terminate).
my $timer = 20;
sub catch_alarm {
    syslog 'err', "Alarm: timeout expired ($timer seconds).";
    closelog();
    exit 1;
}
$SIG{'ALRM'} = \&catch_alarm;
alarm($timer);

openlog 'sipsak-notify', 'pid cons', 'daemon';
sub sys_die($) { syslog('err',$_[0]); exit 1; }

# Refer to RFC 3842 for SIP MWI.

my $vmpath      = shift;
my $CONTEXT     = shift;
my $EXTENSION   = shift;
my $PROXY       = shift;
my $CP_SERVER   = $PROXY;

sys_die "Usage: sipsak-notify.pl <vmpath> <context> <extension> <proxy>"
    unless defined $vmpath and defined $CONTEXT and defined $EXTENSION and defined $PROXY;

sys_die "sipsak-notify.pl: No such directory $vmpath"
    unless -d $vmpath;
    
my $dir_name = "$vmpath/$CONTEXT/$EXTENSION";

sys_die "sipsak-notify.pl: No such directory $dir_name"
    unless -d $dir_name;

# Note: in CCNQ, the voicemailbox have a format of user_${EXTENSION}

my $VM_ID = $EXTENSION;
$VM_ID =~ s/^user_//;

# Note: ${CONTEXT} not used for now. (No partitioning.)
my $URI         = "${VM_ID}\@${PROXY}";
my $MAILBOX     = "VMo${VM_ID}";

syslog('debug',"sipsak notify $vmpath $CONTEXT $EXTENSION $PROXY $CP_SERVER $URI $MAILBOX");

sub get_msgs($)
{
    my $this_dir = shift;
    opendir my $dir, $this_dir
        or return ();
    my @entries = grep { /^msg.*\.txt/ } readdir $dir;
    closedir $dir;
    return @entries;
}

my @msgs = get_msgs("$dir_name/INBOX");

my $NEW_COUNT   = $#msgs + 1;
my $HAS_MESSAGE = $NEW_COUNT > 0 ? 'yes' : 'no';

@msgs = get_msgs("$dir_name/Old");

my $OLD_COUNT   = $#msgs + 1;

my $RAND        = md5_hex(rand());

my $CONTENT =
    "Messages-Waiting: ${HAS_MESSAGE}\r\n".
    "Voicemail: ${NEW_COUNT}/${OLD_COUNT}\r\n";

my $CONTENT_LENGTH = length($CONTENT);

# Note that sipsak actually has an option to automatically translate \n to \r\n
# so it may not be necessary to do it here.

my $message =
    "NOTIFY sip:${URI} SIP/2.0\r\n".
    "Via: SIP/2.0/UDP ${PROXY}:5060\r\n".
    "From: <sip:${MAILBOX}\@${CP_SERVER}>\r\n".
    "To: <sip:${URI}>\r\n".
    "Contact: <sip:${MAILBOX}\@${CP_SERVER}>\r\n".
    "Call-ID: ${RAND}\@${CP_SERVER}\r\n".
    "CSeq: 1 NOTIFY\r\n".
    "User-Agent: CarrierClass.net VoiceMail\r\n".
    "Event: message-summary\r\n".
    "Content-Type: application/simple-message-summary\r\n".
    "Content-Length: ${CONTENT_LENGTH}\r\n".
    "\r\n".
    $CONTENT;


syslog('info',"sipsak notify Messages-Waiting: ${HAS_MESSAGE} Voicemail: ${NEW_COUNT}/${OLD_COUNT}");

open my $sipsak, "| /usr/bin/sipsak -f - -E udp -s sip:${URI}"
    or sys_die "ERROR: sipsak failed: $!";
print $sipsak $message
    or sys_die "ERROT: sipsak failed: $!";
close $sipsak;

closelog();
exit(0);
